import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


public class MonsterGame extends JFrame{

	public MonsterGame() throws IOException {
		size = new Dimension(800, 800);
		this.setSize(size);
		this.setMinimumSize(new Dimension(300, 300));
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		m = new MonsterImage();
		final JPanel p = new JPanel(null);
		p.setPreferredSize(size);
		p.setOpaque(false);
		p.setBounds(0, 0, size.width, size.height);
		m.setBounds(0, 0, m.getWidth(), m.getHeight());
		counter = COUNTER_MAX;
		timer = new JLabel(counter+"");
		timer.setFont(new Font("Mio", Font.BOLD, 50));
		timer.setForeground(Color.RED);
		timer.setBounds(size.width - timer.getPreferredSize().width - 60, size.height - timer.getPreferredSize().height - 50, 
				timer.getPreferredSize().width, timer.getPreferredSize().height);
		final DragPanel d = new DragPanel(size, this);
		d.setBounds(0, 0, size.width, size.height);
		back = new BackGroundPanel(size);
		back.setBounds(0, 0, size.width, size.height);
		p.add(timer);
		p.add(back);
		this.getLayeredPane().add(p, JLayeredPane.DEFAULT_LAYER);
		this.getLayeredPane().add(m, JLayeredPane.PALETTE_LAYER);
		this.getLayeredPane().add(d, JLayeredPane.MODAL_LAYER);
		this.addComponentListener(new ComponentListener() {
			public void componentShown(ComponentEvent e) {}
			public void componentResized(ComponentEvent e) {
				size = getSize();
				timer.setBounds(size.width - timer.getPreferredSize().width - 60, size.height - timer.getPreferredSize().height - 50, 
						timer.getPreferredSize().width, timer.getPreferredSize().height);
				p.setBounds(0, 0, size.width, size.height);
				d.setPreferredSize(size);
				back.setPreferredSize(size);
				getLayeredPane().revalidate();
			}
			public void componentMoved(ComponentEvent e) {}
			public void componentHidden(ComponentEvent e) {}
		});
		
		t = new Timer();
		t.scheduleAtFixedRate(new TimerLabelUpdater(), 1000, 1000);
		movingMonster = new MonsterMoving();
		movingMonster.start();
	}
	
	public void clicked(final Point p){
		if(!clicked){
    		clicked = true;
    		clickThread = new ClickThread(p);
    		clickThread.start();
		}
	}
	
	class ClickThread extends Thread{
		public ClickThread(Point p) {
			stop = false;
			this.p = p;
		}
		public void run() {
			try{
				Rectangle r = m.getBounds();
				Rectangle sword = new Rectangle(p.x+70, p.y-200, 130, 160);
				if(r.intersects(sword)){
					m.setVisible(false);
					back.addBlood(new Point(r.getLocation()));
					m.changeMonster();
					hit++;
					Thread.sleep(2000);
					if(!stop)
						m.setVisible(true);
				}else
					miss++;
				clicked = false;
			}catch(InterruptedException e){
				
			}
		}
		public void setStop(){
			stop = true;
		}
		private boolean stop;
		private Point p;
	}
	
	class MonsterMoving extends Thread{
		public MonsterMoving() {
			stop = false;
		}
		public void run() {
			try{
				Random r = new Random();
				while(!stop){
					int x = r.nextInt(size.width - m.getWidth());
					int y = r.nextInt(size.height - 30 - m.getHeight());
					Point position = m.getBounds().getLocation();
					for(int i = 1; i<=20 && !stop; i++){
						int newX = 0, newY = 0;
						if(position.x > x)
							newX = position.x - ((position.x - x)/20 * i);
						else
							newX = position.x + ((x - position.x)/20 * i);
						if(position.y > y)
							newY = position.y - ((position.y - y)/20 * i);
						else
							newY = position.y + ((y - position.y)/20 * i);
						
						m.setBounds(newX, newY, m.getWidth(), m.getHeight());
						m.revalidate();
						Thread.sleep(25);
					}
					Thread.sleep(400);
				}
			}catch(InterruptedException e){
				
			}
		}
		public void setStop(){
			stop = true;
		}
		private boolean stop;
	}
	
	class TimerLabelUpdater extends TimerTask{
		public void run() {
			counter--;
			timer.setText(counter+"");
			if(counter<10 && counter>0){
				timer.setFont(new Font("Mio", Font.BOLD, 50));
				timer.setForeground(Color.RED);
				timer.setBounds(size.width - timer.getPreferredSize().width - 60, size.height - timer.getPreferredSize().height - 50, 
						timer.getPreferredSize().width, timer.getPreferredSize().height);
			}else if(counter == COUNTER_MAX-1){
				timer.setFont(new Font("Mio", Font.BOLD, 40));
				timer.setForeground(Color.BLACK);
				timer.setBounds(size.width - timer.getPreferredSize().width - 60, size.height - timer.getPreferredSize().height - 50, 
						timer.getPreferredSize().width, timer.getPreferredSize().height);
			}else if(counter == 0){
				//score
				movingMonster.setStop();
				t.cancel();
				if(clicked)
					clickThread.setStop();
				Object[] possibleValues = { "Restart", "Exit"};
				int selectedValue = JOptionPane.showOptionDialog(MonsterGame.this, "HitRate: "+((hit+miss)==0?"-":(hit*100/(hit+miss))+"%")+"\nDefeated: "+hit, "Score", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]);
				if(selectedValue == JOptionPane.CLOSED_OPTION || selectedValue == 1){
					MonsterGame.this.dispose();
					System.exit(0);
				}else{
					hit=0;
					miss = 0;
					counter = COUNTER_MAX;
					timer.setText(counter+"");
					timer.setFont(new Font("Mio", Font.BOLD, 50));
					timer.setForeground(Color.RED);
					timer.setBounds(size.width - timer.getPreferredSize().width - 60, size.height - timer.getPreferredSize().height - 50, 
							timer.getPreferredSize().width, timer.getPreferredSize().height);
					m.setVisible(true);
					movingMonster = new MonsterMoving();
					movingMonster.start();
					t = new Timer();
					t.scheduleAtFixedRate(new TimerLabelUpdater(), 1000, 1000);
				}
			}
			timer.revalidate();
		}
	}
	
	private static final long serialVersionUID = 4460096816073671966L;
	private static final File score = new File("scores");
	private static final int COUNTER_MAX = 30;
	private Dimension size;
	private MonsterImage m;
	private BackGroundPanel back;
	private JLabel timer;
	private int counter, hit =0, miss=0;
	private MonsterMoving movingMonster;
	private ClickThread clickThread;
	private Timer t;
	private boolean clicked;
	
	public static void main(String[] args){
		try {
			new MonsterGame().setVisible(true);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


